/**
 * Crazy Data
 *  @license by CrazyYi.
 *  @version v1.0.0 20200206
 *           v1.1.0 20200228: 单独保存pkey，且初始化和其他组件保持一致
 *           v1.2.0 20200322: 完善注释和说明
 *
 *  Only use for table data process
 *
 */
layui.define(['table', 'jquery', 'crazyTool'], function (exports) {
    const MOD_NAME = 'crazyData'

    let $ = layui.jquery,
        crazyTool = layui.crazyTool

    let gTbId = ''; // table elem id
    let gTbDataId = ''; // table curr data id, only use for cache identity
    let gRes = {
        code: 0,
        count: 0,
        data: [],
        msg: '',
        totalRow: {}, // layui2.5.6新增，在接口返回参数中，可以直接带上该参数。详见：https://www.layui.com/doc/modules/table.html#cols
    }; // table.render done 回调返回的res格式，仅供参考格式，实际结果保存在本地缓存中

    // v1.1.0，单独设置如下参数
    const defaultSet = {
        pkey: {field: 'id', name: 'id'}, // v1.1.0，单独保存,主表的索引字段field，以及对应http请求的名称name
        mark: {
            strConn: ',', // 字符串 拼接字符（说明是数组），暂不支持修改
            arrConn: ',', // 转换成HTTP请求的数组拼接字符
            rangeConn: '~', // 范围拼接字符，说明该字段是范围，比如1~8
        }, // 数据参数字符
    };
    let gSet = {};
    let gPKey = {};

    /**
     * 保存 data 的主要参数
     * @type {{
     *      getCol: (function(*=, *=): Array),
     *      getShowTr: (function(*=): (*|Array)),
     *      getCell: (function(*=, *=): string),
     *      getIndexs: (function(): (*|Array)),
     *      checkDatas: (function(): (boolean|Array)),
     *      getColArray: (function(*=, *=): Array),
     *      update: update,
     *      getKeys: (function(): (*|Array)),
     *      getRow: (function(*): *),
     *      render: render,
     *      getCount: (function(): number),
     *      }}
     */
    let dataIns = {
        /**
         * 初始化
         * @param myTable
         * @param res
         */
        render: function (myTable, res) {
            gTbId = myTable.id;
            gTbDataId = gTbId + '_data';
            gRes = res;

            $.extend(true, gSet, defaultSet, myTable.setting); // v1.1.0，独立设置信息
            $.extend(gPKey, gSet.pkey);
        },
        /**
         * 获取当前缓存数据的长度
         * @returns {number}
         */
        getCount: function () {
            return gRes.count;
        },

        /**
         * 获取 field 列的取值，根据unique判断是否去重（默认=去重）
         * @param field
         * @param unique
         * @returns {Array}
         */
        getCol: function (field, unique) {
            unique = unique || true;
            let col = [];
            $.each(gRes.data, function (iRow, row) {
                if (row.hasOwnProperty(field)) {
                    let curV = row[field];
                    if (!!curV) {
                        if (!unique) {
                            col.push(curV);
                        } else {
                            if (!col.includes(curV)) {
                                col.push(curV);
                            }
                        }
                    }
                }
            });
            return col;
        },
        /**
         * 获取 索引=index 的行记录
         * @param index
         * @returns {*}
         */
        getRow: function (index) {
            return gRes.data[index]
        },
        /**
         * 获取 索引=index，字段field 的值
         * @param index
         * @param field
         * @returns {string}
         */
        getCell: function (index, field) {
            let row = this.getRow(index);
            return row.hasOwnProperty(field) ? row[field] : ''
        },
        /**
         * 获取同一个field 的所有值（默认去掉重复值）
         * @param field
         * @param unique
         * @returns {Array}
         */
        getColArray: function (field, unique) {
            let col = this.getCol(field, unique);
            let arr = [];
            $.each(col, function (iRow, cell) {
                arr.push({key: cell, value: cell});
            });
            return arr;
        },
        /**
         * 获得 LAY_TABLE_INDEX 列
         * @returns {*|Array}
         */
        getIndexs: function () {
            return this.getCol('LAY_TABLE_INDEX');
        },
        /**
         * 获取匹配的TR的data-index ， return trsIndex[]
         * @param filterValues
         * @returns {*|Array}
         */
        getShowTr: function (filterValues) {
            let trsIndex = [];
            filterValues = $.isArray(filterValues) ? filterValues : (filterValues.constructor === Object ? filterValues : {});
            // console.log('curr filter values', filterValues)
            $.each(filterValues, function (key, filterValue) {
                let this_trsIndex = [];
                // 获取这一次过滤的匹配，从全局数据中进行查找
                $.each(gRes.data, function (iRow, row) {
                    if (!row.hasOwnProperty(key)) {
                        return false; // break, 如果没有这个字段，就不用查找了
                    }

                    let curV = row[key] || '';
                    let index = row.LAY_TABLE_INDEX || iRow; // 当前行的index
                    // console.log('each row index=' + index, 'value=', curV, 'search value=', filterValue)
                    if (crazyTool.inArrayOrSame(curV, filterValue) >= 0) {
                        this_trsIndex.push(index);
                    }
                });
                // log.print('this_trsIndex ' + key, this_trsIndex);

                //取最终结果 合并数组后去相同值
                //第一次 不合并
                if (trsIndex.length <= 0) {
                    trsIndex = this_trsIndex
                } else {
                    if (this_trsIndex.length > 0) {
                        //这一次有值 和前面N次取相同值
                        trsIndex = crazyTool.getSameArray(trsIndex, this_trsIndex);
                    } else {
                        //这一次没值 前面N次有值,如果字符串过滤未有值 就显示空
                        trsIndex = $.isArray(filterValue) ? trsIndex : [];
                    }
                }
            });
            // console.log('curr show index', trsIndex);
            return crazyTool.uniqueObjArray(trsIndex);
        },
        /**
         * 获取索引列的取值，数组，且去重，v1.2.0
         * @returns {*|Array}
         */
        getKeys: function () {
            return this.getCol(gPKey.field, true);
        },
        /**
         * 本地缓存数据的更新，v1.2.0
         * @param update
         */
        update: function (update) {
            let res = gRes;

            let pkn = gPKey.name; // 主索引名称
            let pkf = gPKey.field; // 主索引字段名
            let datas = res.data;
            $.each(datas, function (iRow, row) {
                if (crazyTool.compare(row[pkf], update[pkn], false)) {
                    $.each(update, function (k, v) {
                        // 将不属于主索引的其他字段保存，且该字段在数据中本身存在
                        if (!crazyTool.compare(k, pkn, false) && $.inArray(k, datas[iRow])) {
                            datas[iRow][k] = v;
                        }
                    });
                }
            });
            // console.log('crazyData | update datas =', datas);
            gRes.data = datas;
        },
        /**
         * 根据 layui table 的checkStatus 方法进行扩展，返回rows,ids, where，v1.2.0
         * @returns {boolean|{data: ({length}|*), ids: Array, where}}
         */
        checkDatas: function () {
            let pkn = gPKey.name; // 主索引名称
            let pkf = gPKey.field; // 主索引字段名
            let checkStatus = table.checkStatus(gTbId);
            let rows = checkStatus.data;
            if (!rows.length) {
                return false;
            }

            let ids = [], where = {};
            $.each(rows, function (i, row) {
                ids.push(row[pkf]);
            });
            if (!ids.length) {
                return false;
            }
            where[pkn] = ids;

            return {data: rows, ids: ids, where: where};
        },
    };

    /**
     * 输出接口 gTable
     */
    exports(MOD_NAME, dataIns);
});